﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using Baosight.Ccs.Mail.Properties;
using System.Net;
using System.IO;
using System.Data.Linq;


namespace Baosight.Ccs.Mail
{
    public class MailManager
    {

        private static MailManager instance = new MailManager();

        public static MailManager Instance
        {
            get { return MailManager.instance; }
            set { MailManager.instance = value; }
        }


        /// <summary>
        /// 发送邮件
        /// <remarks>
        /// 将邮件保存到发送列表中
        /// </remarks>
        /// </summary>
        /// <param name="msg">邮件</param>
        public void SendMail(Mail mail)
        {
            using (MailDBDataContext db = GetDB())
            {
                mail.MailId = Guid.NewGuid();
                mail.Status = Convert.ToInt16(MailStatus.ToBeSend);
                db.Mails.InsertOnSubmit(mail);
                db.SubmitChanges();
            }
        }

        /// <summary>
        /// 将邮件持久化并标记为未处理
        /// </summary>
        /// <param name="msg"></param>
        public void PersistUnhandledMail(Mail msg)
        {
            using (MailDBDataContext db = GetDB())
            {
                msg.Status = Convert.ToInt16(MailStatus.Unhandled);
                db.Mails.InsertOnSubmit(msg);
                db.SubmitChanges();
            }
        }

        /// <summary>
        /// 将指定的邮件标记变更成指定状态
        /// </summary>
        /// <param name="msg"></param>
        public void ChangeMailStatus(Mail mail,MailStatus newStatus)
        {
            using (MailDBDataContext db = GetDB())
            {
                mail.Status = Convert.ToInt16(newStatus);
                db.Mails.Attach(mail);
                db.SubmitChanges();
            }
        }

        /// <summary>
        /// 获取指定状态的邮件的列表
        /// </summary>
        /// <param name="status"></param>
        /// <returns></returns>
        public List<Mail> GetMailsByStatus(MailStatus status)
        {
            using (MailDBDataContext db = GetDB())
            {
                db.ObjectTrackingEnabled = false;
                db.DeferredLoadingEnabled = false;
                DataLoadOptions option = new DataLoadOptions();
                option.LoadWith<Mail>(mail => mail.Attachments);
                db.LoadOptions = option;

                var mails = from Mail mail in db.Mails
                                    where mail.Status == Convert.ToInt16(status)
                                    select mail;
                return mails.ToList();
            }
        }


        public void SendMailBySmtp(Mail mail)
        {
            SmtpClient mailClient = new SmtpClient(Settings.Default.SmtpServer);
            mailClient.Credentials = new NetworkCredential(Settings.Default.SmtpUser, Settings.Default.SmtpUserCredential);
            using (MailMessage message = new MailMessage())
            {
                message.From = new MailAddress(Settings.Default.SmtpFromAddress);
                SetAddressCollection(mail.ToAddress, message.To);
                SetAddressCollection(mail.CcAddress, message.CC);
                SetAddressCollection(mail.BccAddress, message.Bcc);
                message.Subject = mail.Subject;
                if (mail.HtmlFlag)
                {
                    message.Body = mail.HtmlBody;
                    message.IsBodyHtml = true;
                }
                else
                {
                    message.Body = mail.StrBody;
                    message.IsBodyHtml = false;
                }

                foreach (Attachment attachment in mail.Attachments)
                {
                    message.Attachments.Add(new System.Net.Mail.Attachment(new MemoryStream(attachment.FileContent.ToArray()), attachment.FileName));
                }
                mailClient.Timeout = Settings.Default.SmtpTimeout;
                mailClient.Send(message);
            }
        }


        private MailDBDataContext GetDB()
        {
            MailDBDataContext db = new MailDBDataContext();
#if DEBUG
            db.Log = Console.Out;
#endif
            //db.ObjectTrackingEnabled = false;
            return db;
        }


        private void SetAddressCollection(string addressList, MailAddressCollection collection)
        {
            if (String.IsNullOrEmpty(addressList))
            {
                return;
            }
            foreach (string address in addressList.Split(',', ';'))
            {
                collection.Add(address);
            }
        }
    }

    
}
